package com.ccteam.shared.data.album
import com.ccteam.model.Resource
import com.ccteam.model.album.AlbumVO
import com.ccteam.model.music.MusicVO
import com.ccteam.network.ApiResult
import com.ccteam.network.ResultVO
import com.ccteam.shared.api.AlbumDataSource
import com.ccteam.shared.api.MusicDataSource
import com.ccteam.shared.data.BaseBoundResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import javax.inject.Inject
import javax.inject.Singleton

/**
 * @author Xiaoc
 * @since 2021/2/17
 */
@Singleton
class AlbumRepository @Inject constructor(
    private val musicDataSource: MusicDataSource,
    private val albumDataSource: AlbumDataSource
) {

    private var albumDetail = mutableMapOf<String,List<AlbumVO>>()
    private var albumMusic = mutableMapOf<String,List<MusicVO>>()

    fun getAlbumInfo(albumId: String): Flow<Resource<List<AlbumVO>>>{
        return object: BaseBoundResource<List<AlbumVO>, ResultVO<AlbumVO>>() {

            override fun loadFromDbOrMemory(): Flow<List<AlbumVO>> {
                return flowOf(albumDetail[albumId] ?: emptyList())
            }

            override suspend fun saveNetworkResult(item: ResultVO<AlbumVO>) {
                val result = if(item.data != null){
                    listOf(item.data!!)
                } else {
                    emptyList()
                }
                albumDetail[albumId] = result
            }

            override fun shouldFetch(data: List<AlbumVO>?): Boolean = true

            override suspend fun fetchFromNetwork(): ApiResult<ResultVO<AlbumVO>> {
                return albumDataSource.getAlbumById(albumId)
            }

        }.asFlow()
    }

    fun getAlbumMusic(albumId: String): Flow<Resource<List<MusicVO>>>{
        return object: BaseBoundResource<List<MusicVO>,ResultVO<List<MusicVO>>>(){
            override fun loadFromDbOrMemory(): Flow<List<MusicVO>> {
                return flow { emit(albumMusic[albumId] ?: mutableListOf<MusicVO>()) }
            }

            override suspend fun saveNetworkResult(item: ResultVO<List<MusicVO>>) {
                albumMusic[albumId] = item.data ?: mutableListOf()
            }

            override fun shouldFetch(data: List<MusicVO>?): Boolean = true

            override suspend fun fetchFromNetwork(): ApiResult<ResultVO<List<MusicVO>>> {
                return musicDataSource.getMusicByAlbumId(albumId)
            }

        }.asFlow()
    }
}